package com.company.dcm.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.dcm.common.R;
import com.company.dcm.constant.CountConstant;
import com.company.dcm.dto.CountDto;
import com.company.dcm.dto.MESDto;
import com.company.dcm.entity.MES_Camera;
import com.company.dcm.dto.R_ClothSheetDto;
import com.company.dcm.entity.*;
import com.company.dcm.server.protocol.enums.ProtocolMessageTypeEnum;
import com.company.dcm.server.protocol.enums.ProtocolTaskOptionEnum;
import com.company.dcm.server.tcp.ConnectionManager;
import com.company.dcm.server.tcp.MessageSender;
import com.company.dcm.service.*;
import com.company.dcm.utils.StringUtils;
import com.company.dcm.utils.excel.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/MES")
public class MESController {
    @Autowired
    private Device_otaService deviceOtaService;
    @Autowired
    private R_ClothSheetService r_clothSheetService;
    @Autowired
    private R_ClothSheetDtoService r_clothSheetDtoService;
    @Autowired
    private R_ClothSheetDetailService r_clothSheetDetailService;
    @Autowired
    private DevService devService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private FactoryService factoryService;
    @Autowired
    private WorkShopService workShopService;
    @Autowired
    private MES_CameraService mes_CameraService;
    @Autowired
    private MES_ImageReportService mes_ImageReportService;
    @Autowired
    private MES_SwitchDetectionService mes_SwitchDetectionService;


    @Value("${dcm.image-prefix}")
    private String prefix;

    @GetMapping("/search")
    public R<Page<MESDto>> search(@RequestParam(name = "pageCurrent", required = false, defaultValue = "1") Integer pageCurrent,
                                  @RequestParam(name = "pageSize", required = false, defaultValue = "3") Integer pageSize,
                                  String deviceCode, String clothCode,
                                  String checkStartDate,String checkEndDate,
                                  Long factoryId, Long id) throws ParseException {
        List<MESDto> result = new ArrayList<>();
        List<R_ClothSheetDetail> r_clothSheetDetails;

        LambdaQueryWrapper<R_ClothSheetDetail> queryWrapperClothSheetDetail = new LambdaQueryWrapper<>();
        Page<R_ClothSheetDetail> page = new Page<>(pageCurrent, pageSize);

        boolean timeFlag = true;

        //1.查出符合的缺陷表（组织sql）
        //1.1按布号对应的设备号和serialNo查询
        if (!StringUtils.isNullOrEmpty(clothCode)) {
            //只包含设备号和serialNo
            R_ClothSheetDto rClothSheet = r_clothSheetDtoService.getDeviceCodeAndSerialByClothCode(clothCode);
            if(rClothSheet!=null){
                queryWrapperClothSheetDetail
                        .eq(R_ClothSheetDetail::getDeviceCode, rClothSheet.getDeviceCode())
                        .eq(R_ClothSheetDetail::getSerialNo,rClothSheet.getSerialNo());
            }
            else return R.error("布匹编号错误！");
        }
        //1.2按机台设备编号查询
        else if (!StringUtils.isNullOrEmpty(deviceCode)) {
            queryWrapperClothSheetDetail.eq(R_ClothSheetDetail::getDeviceCode, deviceCode);
        }
        //1.3按车间查询
        else if(id!=null){
            List<String> deviceCodes = devService.getDeviceCodeByWorkShopId(id);
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
            }else {
                timeFlag =false;
            }
        }
        //1.4按厂房查询
        else if(factoryId!=null){
            List<String> deviceCodes = devService.getDeviceCodeByFactoryId(factoryId);
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
            }
            else {
                timeFlag =false;
            }
        }

        //1.5都没有，按当前权限返回
//        if(factoryId==null&id==null&StringUtils.isNullOrEmpty(deviceCode)&StringUtils.isNullOrEmpty(clothCode)){
        else {
            List<String> deviceCodes = devService.getDeviceCodeByAuth();
            if(deviceCodes!=null&&deviceCodes.size()>0) {
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
            }
            else {
                timeFlag =false;
            }
        }


        //1.6按检测时间查询，查询当天的记录
        if(timeFlag){
            if((!StringUtils.isNullOrEmpty(checkStartDate))&&(!StringUtils.isNullOrEmpty(checkEndDate))) {
                SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    Date checkStartDateTurn = ft.parse(checkStartDate);
                    Date checkEndDateTurn = ft.parse(checkEndDate);
                    queryWrapperClothSheetDetail.between(R_ClothSheetDetail::getCheckDate, checkStartDateTurn, checkEndDateTurn);

                } catch (ParseException e) {
                    return R.error("日期格式不对!");
                }
            }

            //2.按时间倒序查询缺陷表分页
            queryWrapperClothSheetDetail.orderByDesc(R_ClothSheetDetail::getCheckDate);
            Page<R_ClothSheetDetail> r_clothSheetDetailPage = r_clothSheetDetailService.page(page, queryWrapperClothSheetDetail);
            r_clothSheetDetails = r_clothSheetDetailPage.getRecords();

            //3.按缺陷表去缺陷报告表补足剩下的字段
            clothSheetDetails2MESDto(result, r_clothSheetDetails);

            Page<MESDto> pageResult = new Page<>();
            pageResult.setRecords(result);
            pageResult.setCurrent(r_clothSheetDetailPage.getCurrent());
            pageResult.setSize(r_clothSheetDetailPage.getSize());
            pageResult.setTotal(r_clothSheetDetailPage.getTotal());

            return R.success(pageResult);
        }
        return R.success(null);
    }

    @GetMapping("/getClothCodeList")
    public R<List<R_ClothSheetDto>> getClothCodeList(String deviceCode, String checkStartDate,String checkEndDate) throws ParseException {
        LambdaQueryWrapper<R_ClothSheetDto> rClothSheetDtoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        boolean sign = false;
        if(!StringUtils.isNullOrEmpty(deviceCode)){
            rClothSheetDtoLambdaQueryWrapper.eq(R_ClothSheetDto::getDeviceCode,deviceCode);
            sign =true;
        }
        if(!StringUtils.isNullOrEmpty(checkStartDate)&&!StringUtils.isNullOrEmpty(checkEndDate)){
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try{
                Date checkStartDateTurn = ft.parse(checkStartDate);
                Date checkEndDateTurn = ft.parse(checkEndDate);
                rClothSheetDtoLambdaQueryWrapper.between(R_ClothSheetDto::getCheckDate,checkStartDateTurn,checkEndDateTurn);
            }catch (ParseException e){
                return R.error("日期格式不对!");
            }
            List<String> deviceCodes = devService.getDeviceCodeByAuth();
            if(deviceCodes==null&(deviceCodes!=null?deviceCodes.size():0)==0){
                return R.error("当前权限下没有机台！");
            }
            rClothSheetDtoLambdaQueryWrapper.in(R_ClothSheetDto::getDeviceCode,deviceCodes);
            sign =true;
        }
        List<R_ClothSheetDto> r_clothSheetDtoList = new ArrayList<>();

        if(sign){
            rClothSheetDtoLambdaQueryWrapper.isNotNull(R_ClothSheetDto::getClothCode);
            r_clothSheetDtoList = r_clothSheetDtoService.getBaseMapper().selectList(rClothSheetDtoLambdaQueryWrapper);
            r_clothSheetDtoList=r_clothSheetDtoList.stream().filter(r_clothSheet -> !Objects.equals(r_clothSheet.getClothCode(), "")).collect(Collectors.toList());
        }
        Collections.reverse(r_clothSheetDtoList);

        return R.success(r_clothSheetDtoList);
    }

//    @GetMapping("/getBuFeiCodeList")
//    public R<List<R_ClothSheet>> getBuFeiCodeList(String deviceCode, String checkStartDate,String checkEndDate) throws ParseException {
//        LambdaQueryWrapper<R_ClothSheet> rClothSheetLambdaQueryWrapper = new LambdaQueryWrapper<R_ClothSheet>();
//        boolean sign = false;
//        if(!StringUtils.isNullOrEmpty(deviceCode)){
//            rClothSheetLambdaQueryWrapper.eq(R_ClothSheet::getDeviceCode,deviceCode);
//            sign =true;
//        }
//        if(!StringUtils.isNullOrEmpty(checkStartDate)&&!StringUtils.isNullOrEmpty(checkEndDate)){
//            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            try{
//                Date checkStartDateTurn = ft.parse(checkStartDate);
//                Date checkEndDateTurn = ft.parse(checkEndDate);
//                rClothSheetLambdaQueryWrapper.between(R_ClothSheet::getCheckDate,checkStartDateTurn,checkEndDateTurn);
//            }catch (ParseException e){
//                return R.error("日期格式不对!");
//            }
//            List<String> deviceCodes = devService.getDeviceCodeByAuth();
//            if(deviceCodes==null&(deviceCodes!=null?deviceCodes.size():0)==0){
//                return R.error("当前权限下没有机台！");
//            }
//            rClothSheetLambdaQueryWrapper.in(R_ClothSheet::getDeviceCode,deviceCodes);
//            sign =true;
//        }
//        List<R_ClothSheet> r_clothSheetList = new ArrayList<>();
//
//        if(sign){
//            rClothSheetLambdaQueryWrapper.isNotNull(R_ClothSheet::getBuFeiCode);
//            r_clothSheetList = r_clothSheetService.getBaseMapper().selectList(rClothSheetLambdaQueryWrapper);
//            r_clothSheetList=r_clothSheetList.stream().filter(r_clothSheet -> !Objects.equals(r_clothSheet.getBuFeiCode(), "")).collect(Collectors.toList());
//        }
//        Collections.reverse(r_clothSheetList);
//
//        return R.success(r_clothSheetList);
//    }

    @GetMapping("/getDeviceCodeList")
    public R<List<String>> getDeviceCodeList() {
        List<String> list=devService.getDeviceCodeByAuth();
        Collections.reverse(list);
        return R.success(list);
    }

    @GetMapping("/download")
    public R download(HttpServletResponse response, String deviceCode, String clothCode,
                              String checkStartDate, String checkEndDate,
                              Long factoryId, Long id, String userName) throws ParseException {
        if(userName==null|(!StpUtil.isLogin(userName))){
            return R.error("用户未登录！");
        }
        StringBuilder resultName = new StringBuilder();
        SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd");
        resultName.append(formatter.format(new Date(System.currentTimeMillis())));
        resultName.append("疵点文件");

        List<MESDto> MESDtos = new ArrayList<>();
        List<R_ClothSheetDetail> r_clothSheetDetails;

        LambdaQueryWrapper<R_ClothSheetDetail> queryWrapperClothSheetDetail = new LambdaQueryWrapper<>();
        boolean timeFlag = true;

        //1.查出符合的缺陷表（组织sql）
        //1.1按布号对应的设备号和serialNo查询
        if (!StringUtils.isNullOrEmpty(clothCode)) {
            //只包含设备号和serialNo
            //只包含设备号和serialNo
            R_ClothSheetDto rClothSheet = r_clothSheetDtoService.getDeviceCodeAndSerialByClothCode(clothCode);
            if(rClothSheet!=null){
                queryWrapperClothSheetDetail
                        .eq(R_ClothSheetDetail::getDeviceCode, rClothSheet.getDeviceCode())
                        .eq(R_ClothSheetDetail::getSerialNo,rClothSheet.getSerialNo());
            }
            else return R.error("布匹编号错误！");
        }
        //1.2按机台设备编号查询
        else if (!StringUtils.isNullOrEmpty(deviceCode)) {
            queryWrapperClothSheetDetail.eq(R_ClothSheetDetail::getDeviceCode, deviceCode);
        }
        //1.3按车间查询
        else if(id!=null){
            List<String> deviceCodes = devService.getDeviceCodeByWorkShopId(id);
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
            }else {
                timeFlag =false;
            }
        }
        //1.4按厂房查询
        else if(factoryId!=null){
            List<String> deviceCodes = devService.getDeviceCodeByFactoryId(factoryId);
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
            }
            else {
                timeFlag =false;
            }
        }

        //1.5都没有，按当前权限返回
//        if(factoryId==null&id==null&StringUtils.isNullOrEmpty(deviceCode)&StringUtils.isNullOrEmpty(clothCode)){
        else {
            List<String> deviceCodes = devService.getDeviceCodeByAuth(userName);
            if(deviceCodes!=null&&deviceCodes.size()>0) {
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
            }
            else {
                timeFlag =false;
            }
        }

        //1.6按检测时间查询
        if(timeFlag){
            if((!StringUtils.isNullOrEmpty(checkStartDate))&&(!StringUtils.isNullOrEmpty(checkEndDate))){
                SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try{
                    Date checkStartDateTurn = ft.parse(checkStartDate);
                    Date checkEndDateTurn = ft.parse(checkEndDate);
                    queryWrapperClothSheetDetail.between(R_ClothSheetDetail::getCheckDate,checkStartDateTurn,checkEndDateTurn);

                }catch (ParseException e){
                    log.warn("日期格式不对!{}  {}",checkStartDate,checkEndDate);
                    return null;
                }
            }
            //2.时间倒序查询缺陷表
            queryWrapperClothSheetDetail.orderByDesc(R_ClothSheetDetail::getCheckDate);
            queryWrapperClothSheetDetail.select(
                    R_ClothSheetDetail::getDeviceCode,
                    R_ClothSheetDetail::getDefectName,
                    R_ClothSheetDetail::getSerialNo,
                    R_ClothSheetDetail::getDeductPoints);
            r_clothSheetDetails = r_clothSheetDetailService.list(queryWrapperClothSheetDetail);

            //3.按缺陷表去缺陷报告表补足剩下的字段
            clothSheetDetails2MESDtoCount(MESDtos, r_clothSheetDetails);

            //4.生成统计报表
            List<CountDto> countDtos = changeMESDtoList2CountDtoList(MESDtos);

            ExcelUtils.export(response,resultName.toString(),countDtos,CountDto.class);
        }
        return null;
    }

    @GetMapping("/download/byClothCode")
    public R downloadByClothCode(HttpServletResponse response, String clothCode, String userName) throws ParseException, IOException {
        if (userName == null | (!StpUtil.isLogin(userName))) {
            return R.error("用户未登录！");
        }
        if (StringUtils.isNullOrEmpty(clothCode)) {
            return R.error("布号不能为空！");
        }

        List<MESDto> MESDtos = new ArrayList<>();
        List<R_ClothSheetDetail> r_clothSheetDetails;

        LambdaQueryWrapper<R_ClothSheetDetail> queryWrapperClothSheetDetail = new LambdaQueryWrapper<>();

        //1.查出符合的缺陷表（组织sql）按布号对应的设备号和serialNo查询
        if (!StringUtils.isNullOrEmpty(clothCode)) {
            //只包含设备号和serialNo
            //只包含设备号和serialNo
            R_ClothSheetDto rClothSheet = r_clothSheetDtoService.getDeviceCodeAndSerialByClothCode(clothCode);
            if(rClothSheet!=null){
                queryWrapperClothSheetDetail
                        .eq(R_ClothSheetDetail::getDeviceCode, rClothSheet.getDeviceCode())
                        .eq(R_ClothSheetDetail::getSerialNo,rClothSheet.getSerialNo());
            }
            else return R.error("布匹编号错误！");
        }

        //2.时间倒序查询缺陷表
        queryWrapperClothSheetDetail.orderByDesc(R_ClothSheetDetail::getCheckDate);
        r_clothSheetDetails = r_clothSheetDetailService.list(queryWrapperClothSheetDetail);

        //3.按缺陷表去缺陷报告表补足剩下的字段
        clothSheetDetails2MESDto(MESDtos, r_clothSheetDetails);

        ExcelUtils.export(response, "布号" + clothCode + "疵点文件", MESDtos, MESDto.class);
        return null;
    }


    @GetMapping("/count")
    public R count(String deviceCode,String clothCode,
                   String checkStartDate,String checkEndDate,
                   Long factoryId, Long id) throws ParseException {
        List<MESDto> MESDtos = new ArrayList<>();
        List<R_ClothSheetDetail> r_clothSheetDetails;

        LambdaQueryWrapper<R_ClothSheetDetail> queryWrapperClothSheetDetail = new LambdaQueryWrapper<>();

        //1.查出符合的缺陷表（组织sql）
        //1.1按布号对应的设备号和serialNo查询
        int resultKind = CountConstant.INIT;
        if (!StringUtils.isNullOrEmpty(clothCode)) {
            //只包含设备号和serialNo
            //只包含设备号和serialNo
            R_ClothSheetDto rClothSheet = r_clothSheetDtoService.getDeviceCodeAndSerialByClothCode(clothCode);
            if(rClothSheet!=null){
                queryWrapperClothSheetDetail
                        .eq(R_ClothSheetDetail::getDeviceCode, rClothSheet.getDeviceCode())
                        .eq(R_ClothSheetDetail::getSerialNo,rClothSheet.getSerialNo());
            }
            else return R.error("布匹编号错误！");
            resultKind=CountConstant.CLOTH;
        }
        //1.2按机台设备编号查询
        else if (!StringUtils.isNullOrEmpty(deviceCode)) {
            queryWrapperClothSheetDetail.eq(R_ClothSheetDetail::getDeviceCode, deviceCode);
            resultKind=CountConstant.DEVICE;
        }
        //1.3按车间查询
        else if(id!=null){
            List<String> deviceCodes = devService.getDeviceCodeByWorkShopId(id);
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
                resultKind=CountConstant.WORKSHOP;
            }else {
                return R.error("当前车间没有机台！");
            }

        }
        //1.4按厂房查询
        else if(factoryId!=null){
            List<String> deviceCodes = devService.getDeviceCodeByFactoryId(factoryId);
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
                resultKind=CountConstant.FACTORY;
            }else {
                return R.error("当前厂房没有机台！");
            }
        }
        //1.5都没有，按当前权限返回
//        if(factoryId==null&id==null&StringUtils.isNullOrEmpty(deviceCode)&StringUtils.isNullOrEmpty(clothCode)){
        else {
            List<String> deviceCodes = devService.getDeviceCodeByAuth();
            if(deviceCodes!=null&&deviceCodes.size()>0){
                queryWrapperClothSheetDetail.in(R_ClothSheetDetail::getDeviceCode, deviceCodes);
                resultKind=CountConstant.FACTORY;
            }else {
                return R.error("所属权限没有机台！");
            }
        }
        //1.6按检测时间查询
        if((!StringUtils.isNullOrEmpty(checkStartDate))&&(!StringUtils.isNullOrEmpty(checkEndDate))){
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try{
                Date checkStartDateTurn = ft.parse(checkStartDate);
                Date checkEndDateTurn = ft.parse(checkEndDate);
                queryWrapperClothSheetDetail.between(R_ClothSheetDetail::getCheckDate,checkStartDateTurn,checkEndDateTurn);
            }catch (ParseException e){
                return R.error("日期格式不对!");
            }
        }

        //2.时间倒序查询缺陷表
        queryWrapperClothSheetDetail.orderByDesc(R_ClothSheetDetail::getCheckDate);
        queryWrapperClothSheetDetail.select(
                R_ClothSheetDetail::getDeviceCode,
                R_ClothSheetDetail::getDefectName,
                R_ClothSheetDetail::getSerialNo,
                R_ClothSheetDetail::getDeductPoints);

        r_clothSheetDetails = r_clothSheetDetailService.list(queryWrapperClothSheetDetail);

        //3.按缺陷表去缺陷报告表补足剩下的字段
        clothSheetDetails2MESDtoCount(MESDtos, r_clothSheetDetails);

        //4.生成统计报表
        CountDto countDto = null;
        switch (resultKind){
            case CountConstant.CLOTH:countDto=changeMESDtoList2CountDtoClothCode(MESDtos);break;
            case CountConstant.DEVICE:
            case CountConstant.WORKSHOP:
            case CountConstant.FACTORY:
                countDto=changeMESDtoList2CountDtoOther(MESDtos);break;
        }
        return R.success(countDto);
    }

    /**
     *                          远程设置图片上报
     * @param
     * @return                  成功：code为 1
     *                          失败：code为其他值，data 是错误信息
     */
    @PostMapping("/remote/set/image/report")
    public R remoteSetImageReport(@RequestParam(name = "operate")Integer operate,
                                  @RequestParam(name = "duration")Long duration,
                                  @RequestParam(name = "gap")Long gap,
                                  @RequestParam(name = "equipment_no")String equipment_no) throws IOException {
        if(operate==1){
            if(duration==null||gap==null)
                return R.error("缺少参数");
        }
        MES_ImageReport mesImageReport = new MES_ImageReport();
        mesImageReport.setSetTime(new Date());
        mesImageReport.setUsed(0);
        mesImageReport.setOperate(operate);
        mesImageReport.setDuration(duration);
        mesImageReport.setGap(gap);
        mesImageReport.setEquipment_no(equipment_no);
        boolean b = mes_ImageReportService.save(mesImageReport);
        if(b){
            byte[] bytes = MessageSender.handleMessage(ProtocolMessageTypeEnum.DATA_PASSTHROUGH_PACKET,
                                                        ProtocolTaskOptionEnum.GET_MES_IMAGE_REPORT);
            MessageSender.sendMessage(equipment_no,bytes);
            return R.success("设置成功");
        }
        return R.error("设置失败");
    }

    /**
     *
     * @return  成功：code为 1，data是图片上报设置
     *          失败：code为其他值，data是错误信息
     */
    @GetMapping("/remote/get/image/report")
    public R remoteGetImageReport(@RequestParam(name = "equipment_no")String equipment_no) {
        MES_ImageReport mesImageReport = mes_ImageReportService.query().eq("equipment_no", equipment_no)
                .orderByDesc("set_time").last("LIMIT 1").one();
        if(mesImageReport==null)return R.error("查询不到图片上报设置对应数据");
        return R.success(mesImageReport);
    }

    /**
     *          设置操作
     * @param
     * @return  成功：code为 1，
     *          失败：code为其他值，data是错误信息
     */
    @PostMapping("/remote/set/switch/detection")
    public R remoteSetSwitchDetection(@RequestParam(name = "operate")Integer operate,
                                      @RequestParam(name = "equipment_no")String equipment_no) throws IOException {
        if(operate==null||equipment_no==null)
            return R.error("缺少参数");
        MES_SwitchDetection mesSwitchDetection = new MES_SwitchDetection();
        mesSwitchDetection.setEquipment_no(equipment_no);
        mesSwitchDetection.setSetTime(new Date());
        mesSwitchDetection.setUsed(0);
        mesSwitchDetection.setOperate(operate);
        boolean b = mes_SwitchDetectionService.save(mesSwitchDetection);
        if (b) {
            byte[] bytes = MessageSender.handleMessage(ProtocolMessageTypeEnum.DATA_PASSTHROUGH_PACKET,
                    ProtocolTaskOptionEnum.GET_MES_SWITCH_DETECTION);
            MessageSender.sendMessage(equipment_no,bytes);
            return R.success("设置成功");
        }
        return R.error("设置失败");
    }


    /**
     *         获取开关检测情况
     * @return 成功：code为 1，data 是检测到的开关的情况，0：关闭，1：开启
     *         失败：code为其他值， data 是错误信息
     */
    @GetMapping("/remote/get/switch/detection")
    public R remoteGetSwitchDetection(@RequestParam String equipment_no){
        if (equipment_no==null)return R.error("缺少参数");
        MES_SwitchDetection mesSwitchDetection = mes_SwitchDetectionService.query().eq("equipment_no", equipment_no)
                .orderByDesc("set_time").last("LIMIT 1").one();
        if(mesSwitchDetection==null)return R.error("查询不到开关检测对应数据");
        return R.success(mesSwitchDetection);
    }

    /**
     *                      获取相机参数
     * @param
     * @return              成功：code为 1
     *                      失败：code为其他值，data 是错误信息
     */
    @PostMapping("/remote/set/camera/parameters")
    public R remoteSetParameters(@RequestParam(name = "hue")Float hue,
                                 @RequestParam(name = "gamma")Float gamma,
                                 @RequestParam(name = "brightness")Float brightness,
                                 @RequestParam(name = "exposure")Float exposure,
                                 @RequestParam(name = "contrast")Float contrast,
                                 @RequestParam(name = "backlightContrast")Float backlightContrast,
                                 @RequestParam(name = "saturation")Float saturation,
                                 @RequestParam(name = "sharpness")Float sharpness,
                                 @RequestParam(name = "whiteBalance")Float whiteBalance,
                                 @RequestParam(name = "equipment_no")String equipment_no) throws IOException {

        if(hue==null||gamma==null
            ||brightness==null||exposure==null
            ||contrast==null||backlightContrast==null
            ||saturation==null||sharpness==null
            ||whiteBalance==null||equipment_no==null)
            return R.error("缺少参数");
        MES_Camera mesCamera = new MES_Camera();
        mesCamera.setHue(hue);
        mesCamera.setGamma(gamma);
        mesCamera.setBrightness(brightness);
        mesCamera.setExposure(exposure);
        mesCamera.setContrast(contrast);
        mesCamera.setBacklightContrast(backlightContrast);
        mesCamera.setSaturation(saturation);
        mesCamera.setSharpness(sharpness);
        mesCamera.setWhiteBalance(whiteBalance);
        mesCamera.setEquipment_no(equipment_no);
        mesCamera.setSetTime(new Date());
        mesCamera.setUsed(0);
        boolean save = mes_CameraService.save(mesCamera);
        if(save){
            byte[] bytes = MessageSender.handleMessage(ProtocolMessageTypeEnum.INFORMATION,
                    ProtocolTaskOptionEnum.GET_MES_CAMERA);
            MessageSender.sendMessage(equipment_no,bytes);


            return R.success("设置成功");
        }
        return R.error("设置失败");
    }

    /**
     *          设置相机参数
     * @return  成功：code为 1，data是 MES_Camera 对象
     *          失败：code为其他值，data是错误信息
     */
    @GetMapping("/remote/get/camera/parameters")
    public R remoteGetParameters(@RequestParam String equipment_no){
        System.out.println(equipment_no);
        MES_Camera mesCamera = mes_CameraService.query().eq("equipment_no", equipment_no)
                .orderByDesc("set_time").last("LIMIT 1").one();
        if(mesCamera==null)return R.error("查询不到相机参数对应数据");
        return R.success(mesCamera);
    }

//    @GetMapping("/remote/get/equipmentNum/list")
//    public R getEquipmentNumList(){
//        Map<String, String> serialToIpPort = ConnectionManager.serialToIpPort;
//        List<String>list = new ArrayList<>(serialToIpPort.keySet());
//        System.out.println(list);
//
//        List<String> result = new ArrayList<>();
//
//        for (String num : list){
//            if (!num.contains("/")){
//                result.add(num);
//            }
//        }
//
//        return R.success(result);
//    }

    @GetMapping("/remote/get/equipmentNum/list")
    public R getEquipmentNumList(@RequestParam String product_type){
        List<Device_Ota> deviceOtas = deviceOtaService.getList(product_type);

        return R.success(deviceOtas);

    }

    @PostMapping("/remote/set/equipmentNum/upgradeUponStartup")
    public R setEquipmentNumUpgradeUponStartup(@RequestBody List<Integer> deviceIds){
        if (deviceOtaService.setUpgradeUponStartup(deviceIds)){
            return R.success("设置成功");
        }else {
            return R.error("设置失败");
        }



    }

    public void clothSheetDetails2MESDto(List<MESDto> result, List<R_ClothSheetDetail> r_clothSheetDetails) {
        Map<String,R_ClothSheet> r_clothSheetMap = new HashMap<>();
        for (R_ClothSheetDetail clothSheetDetail : r_clothSheetDetails) {
            //3.1查出对应缺陷报告表(进行缓存)
            R_ClothSheet r_clothSheet=r_clothSheetMap.get(clothSheetDetail.getDeviceCode() + "-" + clothSheetDetail.getSerialNo());
            if(r_clothSheet==null){
                r_clothSheet = r_clothSheetService
                        .getR_ClothSheetByDeviceCodeAndSerialNo(clothSheetDetail.getDeviceCode(), clothSheetDetail.getSerialNo());
                r_clothSheetMap.put(clothSheetDetail.getDeviceCode() + "-" + clothSheetDetail.getSerialNo(),r_clothSheet);
            }

            //3.2r_clothSheet补足信息
            MESDto mesDto = new MESDto();
            if(r_clothSheet!=null){
                mesDto.setClothCode(r_clothSheet.getBuFeiCode());
                mesDto.setClothInspector(r_clothSheet.getClothInspector());
                mesDto.setWeaver(r_clothSheet.getWeaver());
            }

            //3.3clothSheetDetail补足信息
            mesDto.setDeviceCode(clothSheetDetail.getDeviceCode());
            mesDto.setCheckDate(clothSheetDetail.getCheckDate());
            mesDto.setCircleNum(clothSheetDetail.getCircleNum());
            mesDto.setCoordinate(clothSheetDetail.getLuCoordinate() + "--" + clothSheetDetail.getRdCoordinate());
            mesDto.setDeductPoints(clothSheetDetail.getDeductPoints());
            mesDto.setDefectName(clothSheetDetail.getDefectName());
            mesDto.setIsStop(clothSheetDetail.getIsStop());
            mesDto.setDefectProbability(clothSheetDetail.getDefectProbability());

            //3.4拼接图片url
            String url=prefix+clothSheetDetail
                    .getPicRelativePath().replaceAll("\\\\","/")
                    +"/"+clothSheetDetail.getPictureName();
            mesDto.setUrl(url);
            //3.5加入结果集
            result.add(mesDto);
        }
    }

    public void clothSheetDetails2MESDtoCount(List<MESDto> result, List<R_ClothSheetDetail> r_clothSheetDetails) {
        Map<String,R_ClothSheet> r_clothSheetMap = new HashMap<>();
        for (R_ClothSheetDetail clothSheetDetail : r_clothSheetDetails) {
            //3.1查出对应缺陷报告表(进行缓存)
            R_ClothSheet r_clothSheet=r_clothSheetMap.get(clothSheetDetail.getDeviceCode() + "-" + clothSheetDetail.getSerialNo());
            if(r_clothSheet==null){
                r_clothSheet = r_clothSheetService
                        .getR_ClothSheetByDeviceCodeAndSerialNo(clothSheetDetail.getDeviceCode(), clothSheetDetail.getSerialNo());
                r_clothSheetMap.put(clothSheetDetail.getDeviceCode() + "-" + clothSheetDetail.getSerialNo(),r_clothSheet);
            }

            //3.2r_clothSheet补足信息
            MESDto mesDto = new MESDto();
            if(r_clothSheet!=null){
                mesDto.setClothCode(r_clothSheet.getBuFeiCode());
            }
            //3.3clothSheetDetail补足信息
            mesDto.setDeviceCode(clothSheetDetail.getDeviceCode());
            mesDto.setDeductPoints(clothSheetDetail.getDeductPoints());
            mesDto.setDefectName(clothSheetDetail.getDefectName());
            //3.4加入结果集
            result.add(mesDto);
        }
    }

    //Excel使用
    public List<CountDto> changeMESDtoList2CountDtoList(List<MESDto> mesDtoList){
        Map<String, String> factories=new HashMap<>();
        Map<String, String> workShops=new HashMap<>();
        Map<String, CountDto> count = new HashMap<>();
        for (MESDto mesDto:mesDtoList){
            //查询工厂名，车间名
            if(workShops.get(mesDto.getDeviceCode())==null){
                Dev dev = devService.getBaseMapper().selectOne(new LambdaQueryWrapper<Dev>().eq(Dev::getDeviceCode,mesDto.getDeviceCode()));
                WorkShop workShop = workShopService.getBaseMapper().selectOne(new LambdaQueryWrapper<WorkShop>().eq(WorkShop::getId,dev.getId()));
                Factory factory = factoryService.getBaseMapper().selectOne(new LambdaQueryWrapper<Factory>().eq(Factory::getFactoryId,workShop.getFactoryId()));
                workShops.put(mesDto.getDeviceCode(),workShop.getName());
                factories.put(mesDto.getDeviceCode(),factory.getFactoryName());
            }
            //第一次统计到的布号，为其初始化
            if(count.get(mesDto.getClothCode())==null){
                CountDto countDto=new CountDto();
                countDto.setClothCode(mesDto.getClothCode());
                countDto.setDeviceCode(mesDto.getDeviceCode());
                countDto.setFactoryName(factories.get(mesDto.getDeviceCode()));
                countDto.setWorkShopName(workShops.get(mesDto.getDeviceCode()));

                count.put(mesDto.getClothCode(),countDto);
            }
            //扣分、统计
            CountDto countDto=count.get(mesDto.getClothCode());
            countDefectNameAndDeductPoints(mesDto, countDto);
            count.put(mesDto.getClothCode(),countDto);
        }
        return new ArrayList<>(count.values());
    }

    public CountDto changeMESDtoList2CountDtoClothCode(List<MESDto> mesDtoList) {
        Map<String, String> factories = new HashMap<>();
        Map<String, String> workShops = new HashMap<>();
        CountDto countDto = new CountDto();
        for (MESDto mesDto : mesDtoList) {
            //查询工厂名，车间名
            if (workShops.get(mesDto.getDeviceCode()) == null) {
                Dev dev = devService.getBaseMapper().selectOne(new LambdaQueryWrapper<Dev>().eq(Dev::getDeviceCode, mesDto.getDeviceCode()));
                WorkShop workShop = workShopService.getBaseMapper().selectOne(new LambdaQueryWrapper<WorkShop>().eq(WorkShop::getId, dev.getId()));
                Factory factory = factoryService.getBaseMapper().selectOne(new LambdaQueryWrapper<Factory>().eq(Factory::getFactoryId, workShop.getFactoryId()));
                workShops.put(mesDto.getDeviceCode(), workShop.getName());
                factories.put(mesDto.getDeviceCode(), factory.getFactoryName());
            }

            countDto.setClothCode(mesDto.getClothCode());
            countDto.setDeviceCode(mesDto.getDeviceCode());
            countDto.setFactoryName(factories.get(mesDto.getDeviceCode()));
            countDto.setWorkShopName(workShops.get(mesDto.getDeviceCode()));

            //扣分、统计
            countDefectNameAndDeductPoints(mesDto, countDto);
        }
        return countDto;
    }

    public CountDto changeMESDtoList2CountDtoOther(List<MESDto> mesDtoList){
        CountDto countDto=new CountDto();
        for (MESDto mesDto:mesDtoList){
            //扣分、统计
            countDefectNameAndDeductPoints(mesDto, countDto);
        }
        return countDto;
    }

    public void countDefectNameAndDeductPoints(MESDto mesDto, CountDto countDto) {
        countDto.addDeductPoints(mesDto.getDeductPoints());
        switch (mesDto.getDefectName()){
            case "烂针":countDto.addLanZhen();break;
            case "纵向":countDto.addZhongXiang();break;
            case "线疵":countDto.addXianCi();break;
            case "漏针":countDto.addLouZhen();break;
            case "不规则":countDto.addBuGuiZe();break;
            case "孔洞":countDto.addKongDong();break;
            case "横向":countDto.addHengXiang();break;
            case "掉布":countDto.addDiaoBu();break;
            case "双抽针":countDto.addShuangChouZhen();break;
            case "斑点":countDto.addBanDian();break;
            case "针路":countDto.addZhenLu();break;
        }
    }
}
